package com.iot.practice.designpattern.factorymethod;

import java.util.HashMap;
import java.util.List;
import java.util.Random;

/**
 * <p>HumanFactory 此类用于：</p>
 * <p>@author：hujm</p>
 * <p>@date：2021年01月26日 18:11</p>
 * <p>@remark：
 * 今天讲女娲造人的故事，这个故事梗概是这样的：
 * 很久很久以前，盘古开辟了天地，用身躯造出日月星辰、山川草木，天地一片繁华
 * One day，女娲下界走了一遭，哎！太寂寞，太孤独了，没个会笑的、会哭的、会说话的东东
 * 那怎么办呢？不用愁，女娲，神仙呀，造出来呀，然后捏泥巴，放八卦炉（后来这个成了太白金星的宝贝）中烤，于是就有了人：
 * 我们把这个生产人的过程用Java程序表现出来：
 * </p>
 */
public class HumanFactory {

    /**
     * 定义一个Map，初始化的Human对象都放在这里面
     */
    private static HashMap<String, Human> humanHashMap = new HashMap<>();

    /**
     * 定一个烤箱，泥巴塞进去，人就出来，这个太先进了
     *
     * @return 人
     */
    public static Human createHuman(Class c) {
        // 定义一个类型的人类
        Human human = null;

        try {
            // 如果Map中有Human对象，则直接从中取出来用，不用再初始化了
            if (humanHashMap.containsKey(c.getSimpleName())) {
                human = humanHashMap.get(c.getSimpleName());
            } else {
                // 产生一个人种
                human = (Human) Class.forName(c.getName()).newInstance();
                // 将初始化的human对象放到Map中
                humanHashMap.put(c.getSimpleName(), human);
            }

        } catch (InstantiationException e) {
            // 你要是不说个人种颜色的话，没法烤，要白的黑的，你说话了才好烤
            System.out.println("必须指定人种的颜色");
        } catch (IllegalAccessException e) {
            // 定义的人种有问题，那就烤不出来了，这是...
            System.out.println("人种定义错误！ ");
        } catch (ClassNotFoundException e) {
            // 你随便说个人种，我到哪里给你制造去？！
            System.out.println("混蛋，你指定的人种找不到！ ");
        }

        return human;
    }

    /**
     * 女娲生气了，把一团泥巴塞到八卦炉，哎产生啥人种就啥人种
     *
     * @return 人种
     */
    public static Human createHuman() {
        // 产生一个人种
        Human human = null;
        // 首先是获得有多少个实现类，多少个人种
        List<Class> concreteHumanList = ClassUtils.getAllClassByInterface(Human.class);

        // 八卦炉自己开始想烧出什么人就是什么人
        Random random = new Random();
        int rand = random.nextInt(concreteHumanList.size());
        human = createHuman(concreteHumanList.get(rand));

        return human;
    }

    public static void main(String[] args) {
        System.out.println("simpleName: " + HumanFactory.class.getSimpleName());
        System.out.println("name: " + HumanFactory.class.getName());
        System.out.println("typeName: " + HumanFactory.class.getTypeName());
    }
}
